package com.bbz.core.concurrency.work8;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * Semaphore可以理解为信号量，用于控制资源能够被并发访问的线程数量， 以保证多个线程能够合理的使用特定资源。 Semaphore就相当于一个许可证，
 * 线程需要先通过acquire方法获取该许可证，该线程才能继续往下执行，否则只能在该方法出阻塞等待。
 * 当执行完业务功能后，需要通过release()方法将许可证归还，以便其他线程能够获得许可证继续执行。
 * Semaphore可以用于做流量控制，特别是公共资源有限的应用场景，比如数据库连接。
 * 假如有多个线程读取数据后，需要将数据保存在数据库中，而可用的最大数据库连接只有10个，
 * 这时候就需要使用Semaphore来控制能够并发访问到数据库连接资源的线程个数最多只有10个。
 * 在限制资源使用的应用场景下，Semaphore是特别合适的。
 * 
 * @author binbin.a.zhang
 *
 */
public class SemaphoreDemo {
	// 表示老师只有10支笔
	private static Semaphore semaphore = new Semaphore(3);

	public static void main(String args[]) {
		// 表示50个学生
		ExecutorService service = Executors.newFixedThreadPool(10);
		for (int i = 0; i < 10; i++) {
			service.execute(() -> {
				try {
					System.out.println(Thread.currentThread().getName() + "  同学准备获取笔......");
					semaphore.acquire();
					System.out.println(Thread.currentThread().getName() + "  同学获取到笔");
					System.out.println(Thread.currentThread().getName() + "  填写表格ing.....");
					TimeUnit.SECONDS.sleep(3);
					semaphore.release();
					System.out.println(Thread.currentThread().getName() + "  填写完表格，归还了笔！！！！！！");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			});
		}
		service.shutdown();
	}

}
